(()=>{
     // 泛型接口
    interface IBaseCRUD<T> {
        data:Array<T> 
        add:(t:T)=>T 
        getUserId:(id :number) => T    
    }

    class User {
        id?: number  // ?可选 id
        name: string 
        age: number 

        constructor(name:string, age:number) {
            this.name = name
            this.age = age
        }

    }

    // 定义一个类， 可以针对用户的信息对象进行增删改查
    class UserCRUD implements IBaseCRUD<User>{
       data: Array<User> = []

       add(user: User) : User {
           user.id = Date.now()+Math.random() 
           this.data.push(user)
           return user 
       }

       getUserId(id:number):User {
           return this.data.find(user => user.id === id)
       }
    }
    
    // 实例化添加用户信息对象的类 UserCRUD
    const userCURD: UserCRUD = new UserCRUD()
    userCURD.add(new User('jack', 20))
    userCURD.add(new User('jack', 20))
    const {id} = userCURD.add(new User('lucy', 21))
    console.log(userCURD.data)
    console.log(userCURD.getUserId(id));
    
    // 泛型类
    class GenericClass<T> {
        defaultValue: T 
        add: (x: T, y :T) => T 
    }

    const g1: GenericClass<Number> = new GenericClass<Number>()
    g1.defaultValue = 100 
    g1.add = function (x, y) {
        return x + y 
    }
    console.log(g1.add(g1.defaultValue, 20))


    
    const g2: GenericClass<string> = new GenericClass<string>()
    g2.defaultValue = 'Hello'
    g2.add = function (x, y) {
        return x + y 
    }
    console.log(g2.add(g2.defaultValue, ' World'))

    // 泛型约束
    interface ILength {
        length: number 
    }

    function getLength<T extends ILength>(x: T) : number {
        return x.length
    }

    console.log(getLength<string>('what are you no sha lei'));

})()